package com.gyhy.dumplings.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gyhy.dumplings.common.exception.BizCodeEnum;
import com.gyhy.dumplings.common.utils.R;
import com.gyhy.dumplings.order.dao.OrderDao;
import com.gyhy.dumplings.order.dao.OrderDetailDao;
import com.gyhy.dumplings.order.entity.OrderDetailEntity;
import com.gyhy.dumplings.order.entity.OrderEntity;
import com.gyhy.dumplings.order.feign.WareFeignService;
import com.gyhy.dumplings.order.service.OrderDetailService;
import com.gyhy.dumplings.order.service.OrderService;
import com.gyhy.dumplings.order.vo.OrderDetailVo;
import com.gyhy.dumplings.order.vo.OrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: 光影灰翼
 * @date: 2022-10-09 8:57
 * @version: 1.0
 * @email: 978330688@qq.com
 */
@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {

    @Autowired
    WareFeignService wareFeignService;

    @Autowired
    OrderDao orderDao;

    @Autowired
    OrderDetailService orderDetailService;
    /*
    3、将数据存入数据库（事务+completableFuture+feign）
        3.1、首先计算仓库是否有足够的存量（feign）
            3.2.1、如果存量不足则直接跳转到第4步，并返回仓储不足消息
        3.2、新建一个order，将信息设为待支付，获取orderId
        3.3、修改仓储数量，并将orderDetail存入数据库中
        3.4、待所有orderDetail存入数据库后，计算总价并填入order中,并修改订单状态
    4、返回信息
    */
    @Override
    // @Async("asyncServiceExecutor")
    public String generateOrder(Long u_id, OrderVo orderVo) throws ExecutionException, InterruptedException {
        List<OrderDetailVo> orderDetailVoList = orderVo.getOrderDetails();
        List<OrderDetailEntity> orderDetailEntities = orderDetailVoList.stream()
                .map(OrderDetailVo::convertOrderDetailEntity)
                .collect(Collectors.toList());
        // 3.1、首先计算仓库是否有足够的存量（feign）,有则修改仓储数量，
        R wareUpdate=wareFeignService.updateWare(orderDetailEntities);

        if (wareUpdate.getCode() == 0) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                // 3.2、有则初始化一个order，将信息设为待支付，获取orderId
                Long orderId = this.initOrder(u_id);
                return orderId;
            }).thenApply(orderId -> {
                // 3.3、将orderDetail存入数据库中
                this.saveOrderDetails(orderDetailEntities,orderId);
                return orderId;
            }).thenApply(
                    // 待所有orderDetail存入数据库后，计算总价并填入order中,并修改订单状态
                    orderId -> {
                        this.payOrder(orderDetailEntities,orderId,orderVo.getNote());
                        return String.valueOf(orderId);
                    });

            // 待所有orderDetail存入数据库后，计算总价并填入order中,并修改订单状态，返回orderId
            // future.get();
            // String orderId = future.join();
            // System.out.println(orderId);
            return future.get();


        }else {
            // 如果存量不足则返回错误消息
            return "failed:"+String.valueOf(R.error().getCode());
        }
    }

    @Override
    public Long initOrder(Long u_id) {
        System.out.println("uerId="+u_id);
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setUserId(u_id);
        orderEntity.setState(0);
        orderEntity.setCreateTime(new Date());
        orderDao.insert(orderEntity);
        return orderEntity.getOrderId();
    }

    @Override
    public void saveOrderDetails(List<OrderDetailEntity> orderDetailEntities, Long orderId) {
        List<OrderDetailEntity> newOrderDetailEntities = orderDetailEntities.stream().map(orderDetailEntity -> {
            orderDetailEntity.setOrderId(orderId);
            return orderDetailEntity;
        }).collect(Collectors.toList());
        orderDetailService.saveBatch(newOrderDetailEntities);
    }

    @Override
    public String payOrder(List<OrderDetailEntity> orderDetailEntities,Long orderId,String note) {
        BigDecimal money= BigDecimal.ZERO;
        System.out.println(orderDetailEntities);
        for (OrderDetailEntity orderDetailEntity : orderDetailEntities) {
            System.out.println("单价为"+orderDetailEntity.getProductPrice()+"元，个数为"+orderDetailEntity.getProductNum()+
                    "总价为："+orderDetailEntity.getProductPrice().multiply(BigDecimal.valueOf(orderDetailEntity.getProductNum())));
            money=money.add(orderDetailEntity.getProductPrice().multiply(BigDecimal.valueOf(orderDetailEntity.getProductNum())));
        }
        System.out.println("money:"+money);
        OrderEntity orderEntity=new OrderEntity();
        orderEntity.setOrderId(orderId);
        orderEntity.setMoney(money);
        orderEntity.setState(1);
        orderEntity.setNote(note);
        orderDao.updateById(orderEntity);
        return String.valueOf(orderId);
    }
}
